// -*- c++ -*-
//
// bookmarkapi.h
//
// Copyright (C) 2005 Petter Stokke <ummo@hellokitty.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
//

#ifndef BOOKMARKAPI_H
#define BOOKMARKAPI_H

#include <qobject.h>
#include <qstringlist.h>
#include <qdict.h>
#include <qdatetime.h>
#include <qptrlist.h>

#include <kurl.h>
#include <kio/job.h>
#include <dcopclient.h>

class Post;
class Collection;
class RenameTagJob;
class GetPostsJob;

class BookmarkAPI : public QObject
{
    Q_OBJECT
public:
    BookmarkAPI( QObject* parent = 0, const char* name = "BookmarkAPI" );

    const QString& user() const;

    virtual RenameTagJob* renameTag( const QString& tag, const QString& newTag ) = 0;
    virtual GetPostsJob* getPosts( const QDateTime& lastUpdate ) = 0;

    QPixmap* faviconForURL( const KURL& _url );

signals:
    void userChanged( const QString& userName );
    void jobStatusText( const QString& text );
    void jobProgress( KIO::filesize_t processed, KIO::filesize_t total );
    void jobDone();

protected slots:
    void setUser( const QString& _user );

protected:
    DCOPClient m_dcop;

private:
    QString m_user;
};

class BookmarkAPIJob : public QObject
{
    Q_OBJECT
public:
    BookmarkAPIJob( BookmarkAPI* parent = 0, const char* name = "BookmarkAPIJob" );

signals:
    void failed( BookmarkAPIJob* me );
    void success( BookmarkAPIJob* me );
    void jobDone();
    void jobStatusText( const QString& text );
    void jobProgress( KIO::filesize_t processed, KIO::filesize_t total );

};

class RenameTagJob
{
public:
    virtual QString oldTag() const = 0;
    virtual QString newTag() const = 0;
};

class GetPostsJob
{
public:
    virtual const QPtrList<Post>& posts() const = 0;
    virtual QDateTime updateTime() const = 0;
    virtual bool noUpdateNeeded() const = 0;
};

class Post : public QObject
{
    Q_OBJECT
public:
    Post( QObject* parent = 0, const char* name = 0 );
    Post( const QString& title, const QString& description, const KURL& url, const QStringList& tags, const QString& user, QObject* parent = 0, const char* name = 0 );

    Collection* collection();

    const QString& title() const;
    void setTitle( const QString& _title );
    const QString& description() const;
    void setDescription( const QString& _description );
    const KURL& url() const;
    void setURL( const KURL& _url );
    const QStringList& tags() const;
    void setTags( const QStringList& _tags );
    const QString& user() const;
    void setUser( const QString& _user );
    bool hasTag( const QString& _tag ) const;
    bool hasTags( const QStringList& _tags ) const;
    void renameTag( const QString& _oldTag, const QString& _newTag );
    void addTag( const QString& _tag );
    bool removeTag( const QString& _tag );
    bool matchesQuery( const QString& _query ) const;

    friend QDataStream &operator<<( QDataStream&, const Post& );
    friend QDataStream &operator>>( QDataStream&, Post& );

private:
    QString m_title, m_description;
    KURL m_url;
    QStringList m_tags;
    QString m_user;
};

QDataStream &operator<<( QDataStream&, const Post& );
QDataStream &operator>>( QDataStream&, Post& );

class Collection : public QObject
{
    Q_OBJECT
public:
    Collection( BookmarkAPI* _api, QObject* parent = 0, const char* name = 0 );

    BookmarkAPI* api();

    void clear();
    void addPost( Post* _post );
    void addPosts( const QPtrList<Post>& _posts );
    bool deletePost( Post* _post );
    bool deletePost( const KURL& _url );

    QPtrList<Post> postsWithTags( const QStringList& _tags ) const;
    // QStringList relatedTags( const QStringList& _tags ) const;
    QPtrList<Post> postsMatchingQuery( const QString& _query ) const;
    QStringList tags() const;
    void renameTag( const QString& oldTag, const QString& newTag );

    uint postCount() const;
    uint tagCount() const;
    uint tagCount( const QStringList& tags ) const;

    const QDateTime& lastUpdate() const;
    void setLastUpdate( const QDateTime& _time );

    bool loadData( QDataStream& _stream );
    bool saveData( QDataStream& _stream );

private:
    BookmarkAPI* m_api;
    QDict<Post> m_posts;
    QDateTime m_lastUpdate;
};

#endif
